package com.common.base.fragment;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.common.CommonApplication;
import com.common.R;
import com.common.bean.InfoResult;
import com.common.bean.MsgBean;
import com.common.theme.ThemeHelper;
import com.common.theme.Themed;
import com.common.theme.UiElementInizializer;
import com.common.theme.ViewUtil;
import com.common.ui.barlibrary.ImmersionBar;
import com.common.ui.barlibrary.components.SimpleImmersionOwner;
import com.common.ui.barlibrary.components.SimpleImmersionProxy;
import com.common.ui.loadsir.callback.Callback;
import com.common.ui.loadsir.callback.EmptyCallback;
import com.common.ui.loadsir.callback.ErrorCallback;
import com.common.ui.loadsir.callback.LoadingCallback;
import com.common.ui.loadsir.callback.TimeoutCallback;
import com.common.ui.loadsir.core.LoadService;
import com.common.ui.loadsir.core.LoadSir;
import com.orhanobut.hawk.Hawk;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import butterknife.ButterKnife;
import butterknife.Unbinder;

public abstract class BaseThemeFragment extends Fragment implements SimpleImmersionOwner, UiElementInizializer {
    /**
     * 解决getActivity()空指针
     * 可能你遇到过getActivity()返回null，或者平时运行完好的代码，在“内存重启”之后，调用getActivity()的地方却返回null，报了空指针异常。
     * 大多数情况下的原因：你在调用了getActivity()时，当前的Fragment已经onDetach()了宿主Activity。
     * 比如：你在pop了Fragment之后，该Fragment的异步任务仍然在执行，并且在执行完成后调用了getActivity()方法，这样就会空指针。
     * 解决办法：
     * 更"安全"的方法：(对于Fragment已经onDetach这种情况，我们应该避免在这之后再去调用宿主Activity对象，比如取消这些异步任务，
     * 但我们的团队可能会有粗心大意的情况，所以下面给出的这个方案会保证安全)
     * 在Fragment基类里设置一个Activity mActivity的全局变量，在onAttach(Activity activity)里赋值，
     * 使用mActivity代替getActivity()，保证Fragment即使在onDetach后，仍持有Activity的引用
     * （有引起内存泄露的风险，但是异步任务没停止的情况下，本身就可能已内存泄漏，相比Crash，这种做法“安全”些）
     *
     */
    /**
     * 视图是否已经初初始化
     */
    private Unbinder unbinder;
    public View rootView;
    protected Activity activity;
    private EventBus eventBus;
    private Toast toast = null;
    public LoadService loadService;
    private boolean isFirstLoad = true; // 是否第一次加载
    /**
     * ImmersionBar代理类
     */
    private SimpleImmersionProxy simpleImmersionProxy = new SimpleImmersionProxy(this);

    /**
     * 变色
     */
    private ThemeHelper themeHelper;
    private boolean coloredNavBar;//虚拟导航栏是否有颜色
    private boolean obscuredStatusBar;//是否全透明导航栏
    private boolean applyThemeSingleImgAct;
    private boolean customIconColor;

    //setUserVisibleHint()在Fragment创建时会先被调用一次，传入isVisibleToUser = false
    //如果当前Fragment可见，那么setUserVisibleHint()会再次被调用一次，传入isVisibleToUser = true
    //如果Fragment从可见->不可见，那么setUserVisibleHint()也会被调用，传入isVisibleToUser = false
    //总结：setUserVisibleHint()除了Fragment的可见状态发生变化时会被回调外，在new Fragment()时也会被回调
    //如果我们需要在 Fragment 可见与不可见时干点事，用这个的话就会有多余的回调了，那么就需要重新封装一个
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        simpleImmersionProxy.setUserVisibleHint(isVisibleToUser);
    }

    /**
     * fragment已经关联到activity,这个时候 activity已经传进来了
     * @param context
     */
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        activity = (Activity) context;
    }

    /**
     * 系统创建fragment的时候回调它，在它里面实例化一些变量
     这些个变量主要是:当你 暂停 停止的时候 你想保持的数据
     如果我们要为fragment启动一个后台线程，可以考虑将代码放于此处
     参数:Bundle savedInstance, 用于保存 Fragment 参数,
     Fragement 也可以 重写 onSaveInstanceState(BundleoutState) 方法, 保存Fragement状态
     * @param savedInstanceState
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        themeHelper = ThemeHelper.getInstanceLoaded(getActivity());
    }


    /**
     * 第一次使用的时候 fragment会在这上面画一个layout出来,为了可以画控件 要返回一个 布局的view
     * 当系统用到fragment的时候 fragment就要返回他的view,越快越好,所以尽量在这里不要做耗时操作
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(getLayoutResId(), container, false);
        bind(rootView);
        unbinder = ButterKnife.bind(this, rootView);
        return rootView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if(isSupportLoadSirEnabled()!=null){
            initLoadSir(isSupportLoadSirEnabled());
        }
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        simpleImmersionProxy.onActivityCreated(savedInstanceState);
        eventBus = EventBus.getDefault();
        eventBus.register(this);
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
        updateTheme();
        updateUiElements();
        if (isFirstLoad) {
            // 将数据加载逻辑放到onResume()方法中
            init();
            loadData();
            isFirstLoad = false;
        }
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

    /**
     * 视图销毁的时候讲Fragment是否初始化的状态变为false
     */
    @Override
    public void onDestroyView() {
        super.onDestroyView();
        isFirstLoad = true;
        if(rootView!=null){
            ((ViewGroup)rootView.getParent()).removeView(rootView);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (eventBus != null) {
            eventBus.unregister(this);
        }
        simpleImmersionProxy.onDestroy();
        unbinder.unbind();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        simpleImmersionProxy.onHiddenChanged(hidden);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        simpleImmersionProxy.onConfigurationChanged(newConfig);
    }

    @Override
    public void initImmersionBar() {
        if (isImmersionBarEnabled()) {
            //在BaseActivity里初始化
            ImmersionBar.with(this).init();
        }
    }

    public void updateTheme() {
        themeHelper.updateTheme();
        coloredNavBar = Hawk.get(getString(R.string.preference_colored_nav_bar), false);
        obscuredStatusBar = Hawk.get(getString(R.string.preference_translucent_status_bar), true);
        applyThemeSingleImgAct = Hawk.get("apply_theme_img_act", true);
        customIconColor = Hawk.get(getString(R.string.preference_custom_icon_color), false);
    }

    @Override
    public void updateUiElements() {
        if(rootView!=null){
            for (View view : ViewUtil.getAllChildren(rootView)) {
                if (view instanceof Themed) ((Themed) view).refreshTheme(getThemeHelper());
            }
        }
    }

    @Override
    public boolean immersionBarEnabled() {
        return isImmersionBarEnabled();
    }

    public abstract boolean isImmersionBarEnabled();

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        //悬浮窗授权
        if (requestCode == 0) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(getActivity())) {
                    showToast("授权失败");
                } else {
                    showToast("授权成功");
                }
            }
        }
    }

    public abstract View isSupportLoadSirEnabled();

    public void initLoadSir(View loadSirView){
        LoadSir loadSir = new LoadSir.Builder()
                .addCallback(new LoadingCallback())
                .addCallback(new EmptyCallback())
                .addCallback(new TimeoutCallback())
                .addCallback(new ErrorCallback())
                //.setDefaultCallback(SuccessCallback.class)
                .setDefaultCallback(LoadingCallback.class)
                .build();
        loadService = loadSir.register(loadSirView, new Callback.OnReloadListener() {
            @Override
            public void onReload(View v) {
                loadData();
            }
        });
    }

    /**
     * 返回当前fragment布局文件的id
     *
     * @return
     */
    public abstract int getLayoutResId();

    /**
     * 初始化
     */
    public abstract void init();

    /**
     * 加载网络数据
     */
    public abstract void loadData();

    /**
     * 网络数据返回成功
     */
    protected abstract void onSuccess(int what, InfoResult t);

    /**
     * 网络数据返回失败
     */
    protected abstract void onFail(int what, InfoResult t);

    public EventBus getEventBus() {
        return eventBus;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void handlerMeg(MsgBean msgBean){

    }

    public void showToast(String msg) {
        if (toast == null) {
            toast = Toast.makeText(getActivity().getApplicationContext(), msg, Toast.LENGTH_SHORT);
        } else {
            toast.setText(msg);
        }
        toast.show();
    }

    /**
     * 跳转到权限设置界面
     */
    public void goIntentSetting() {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= 9) {
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.setData(Uri.fromParts("package", CommonApplication.getInstance().getPackageName(), null));
        } else if (Build.VERSION.SDK_INT <= 8) {
            intent.setAction(Intent.ACTION_VIEW);
            intent.setClassName("com.android.settings", "com.android.settings.InstalledAppDetails");
            intent.putExtra("com.android.settings.ApplicationPkgName", CommonApplication.getInstance().getPackageName());
        }
        startActivity(intent);
    }
    /**
     * 跳转到某个Activity
     *
     * @param activity
     * @param targetActivity
     */
    public void switchTo(Activity activity, Class<? extends Activity> targetActivity, boolean finish) {
        switchTo(activity, new Intent(activity, targetActivity),finish);
    }

    public void switchTo(Activity activity, Intent intent, boolean finish) {
        activity.startActivity(intent);
        if(finish){
            getActivity().finish();
        }
        //overridePendingTransition(R.anim.alpha_out, R.anim.alpha_in);
    }

    public void bind(View view){

    }
    public void requestString(String url,int tag){

    }

    public ThemeHelper getThemeHelper() {
        return themeHelper;
    }

    public void setThemeHelper(ThemeHelper themeHelper) {
        this.themeHelper = themeHelper;
    }

    public boolean isColoredNavBar() {
        return coloredNavBar;
    }

    public void setColoredNavBar(boolean coloredNavBar) {
        this.coloredNavBar = coloredNavBar;
    }

    public boolean isObscuredStatusBar() {
        return obscuredStatusBar;
    }

    public void setObscuredStatusBar(boolean obscuredStatusBar) {
        this.obscuredStatusBar = obscuredStatusBar;
    }

    public boolean isApplyThemeSingleImgAct() {
        return applyThemeSingleImgAct;
    }

    public void setApplyThemeSingleImgAct(boolean applyThemeSingleImgAct) {
        this.applyThemeSingleImgAct = applyThemeSingleImgAct;
    }

    public boolean isCustomIconColor() {
        return customIconColor;
    }

    public void setCustomIconColor(boolean customIconColor) {
        this.customIconColor = customIconColor;
    }

    //================================= 方法 ==========================================

    /**
     * 5.0之后
     * 有权查看使用情况的应用(打开使用量数据访问)
     */
    public void openUsedApp(){
        Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
        startActivity(intent);
    }

    /**
     * 打开悬浮窗设置权限
     */
    public void requestSettingCanDrawOverlays() {
        startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + getActivity().getPackageName())), 0);
    }
}
